package com.sanbi.erp.api.vo;

import com.github.pagehelper.Page;
import com.sanbi.common.vo.PageListVo;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 响应操作结果
 * <pre>
 *  {
 *      errno： 错误码，
 *      errmsg：错误消息，
 *      data：  响应数据
 *  }
 * </pre>
 *
 * <p>
 * 错误码：
 * <ul>
 * <li> 0，成功；
 * <li> 4xx，前端错误，说明前端开发者需要重新了解后端接口使用规范：
 * <ul>
 * <li> 401，参数错误，即前端没有传递后端需要的参数；
 * <li> 402，参数值错误，即前端传递的参数值不符合后端接收范围。
 * </ul>
 * <li> 5xx，后端错误，除501外，说明后端开发者应该继续优化代码，尽量避免返回后端错误码：
 * <ul>
 * <li> 501，验证失败，即后端要求用户登录；
 * <li> 502，系统内部错误，即没有合适命名的后端内部错误；
 * <li> 503，业务不支持，即后端虽然定义了接口，但是还没有实现功能；
 * <li> 504，更新数据失效，即后端采用了乐观锁更新，而并发更新时存在数据更新失效；
 * <li> 505，更新数据失败，即后端数据库更新失败（正常情况应该更新成功）。
 * </ul>
 * <li> 6xx，小商城后端业务错误码，
 * 具体见easytao-admin-api模块的AdminResponseCode。
 * <li> 7xx，管理后台后端业务错误码，
 * 具体见easytao-wx-api模块的WxResponseCode。
 * </ul>
 */
@Data
@NoArgsConstructor
public class ResponseVo<T> {
    private final static int Success=200;
    private final static String Message = "成功";
    private final static int Fail=-1;


    //错误码
    private int errno;

    //错误信息
    private String errmsg;

    //返回数据
    private T Data;

    public ResponseVo(int errno, String errmsg){
        this.errno = errno;
        this.errmsg = errmsg;
    }

    ResponseVo(int errno, String errmsg, T data){
        this.errno = errno;
        this.errmsg = errmsg;
        this.setData(data);
    }

    public static <T> ResponseVo<T> ok() {
        return new ResponseVo<>(Success, Message);
    }

    public static <T> ResponseVo<T> ok(T data) {
        return new ResponseVo<>(Success, Message, data);
    }

    public static <T> ResponseVo<T> ok(String errmsg, T data) {
        return new ResponseVo<>(Success, errmsg, data);
    }

    public static <T> ResponseVo<T> okMessage(String errmsg) {
        return new ResponseVo<>(Success, errmsg);
    }

    public static <T> ResponseVo<T> fail() {
        return new ResponseVo<>(Fail,"错误");
    }

    public static <T> ResponseVo<T> fail(String errmsg) {
        return new ResponseVo<>(Fail, errmsg);
    }

    public static <T> ResponseVo<T> fail(int errno, String errmsg) {
        return new ResponseVo<>(errno, errmsg);
    }

    public static <T> ResponseVo<T> fail(int errno, String errmsg, T data) {
        return new ResponseVo<>(errno, errmsg, data);
    }
    /**
     * PageHelper插件分页后的list分页属性获取
     * @param list 分页后的Page对象list
     * @param <T>
     * @return
     */
    public static <T> ResponseVo<PageListVo<T>> okList(List<T> list) {
        PageListVo<T> pageListVo = new PageListVo<>();
        pageListVo.setList(list);
        if (list instanceof Page) {
            Page<T> page = (Page<T>) list;
            pageListVo.setTotal(page.getTotal());
            pageListVo.setPage(page.getPageNum());
            pageListVo.setLimit(page.getPageSize());
            pageListVo.setPages(page.getPages());
        } else {
            pageListVo.setTotal(list.size());
            pageListVo.setPage(1);
            pageListVo.setLimit(list.size());
            pageListVo.setPages(1);
        }
        return ok(pageListVo);
    }

    public static <T> PageListVo<T> okListXYP(List<T> list) {
        PageListVo<T> pageListVo = new PageListVo<>();
        pageListVo.setList(list);
        if (list instanceof Page) {
            Page<T> page = (Page<T>) list;
            pageListVo.setTotal(page.getTotal());
            pageListVo.setPage(page.getPageNum());
            pageListVo.setLimit(page.getPageSize());
            pageListVo.setPages(page.getPages());
        } else {
            pageListVo.setTotal(list.size());
            pageListVo.setPage(1);
            pageListVo.setLimit(list.size());
            pageListVo.setPages(1);
        }
        return pageListVo;
    }

    /**
     * PageHelper的list转换分页属性获取
     * @param
     * @param list <T> 此list为分页后进行数据筛选的Vo
     * @param pagedList <V> 此list为分页后的Page属性list可以获取页号，数据总数，页大小，页总数
     * @return
     */
    public static <T,V> ResponseVo<PageListVo<T>> okList(List<T> list, List<V> pagedList) {
        PageListVo<T> pageListVo = new PageListVo<>();
        pageListVo.setList(list);
        if (pagedList instanceof Page) {
            Page<V> page = (Page<V>) pagedList;
            pageListVo.setTotal(page.getTotal());
            pageListVo.setPage(page.getPageNum());
            pageListVo.setLimit(page.getPageSize());
            pageListVo.setPages(page.getPages());
        } else {
            pageListVo.setTotal(pagedList.size());
            pageListVo.setPage(1);
            pageListVo.setLimit(pagedList.size());
            pageListVo.setPages(1);
        }
        return ok(pageListVo);
    }
}

